package com.infore.remoteControl.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.infore.remoteControl.constant.Constants;
import com.infore.remoteControl.constant.ResultConstants;
import com.infore.remoteControl.entity.protocolEntity.ProtocolData;
import com.infore.remoteControl.enums.ResultStatus;
import com.infore.remoteControl.repository.IProtocolDataRepository;
import com.infore.remoteControl.select.QueryDispatcher;
import com.infore.remoteControl.select.dto.QueryParamDto;
import com.infore.remoteControl.select.util.QueryUtil;
import com.infore.remoteControl.service.IFileService;
import com.infore.remoteControl.service.IProtocolDataService;
import com.infore.remoteControl.util.MyBeanUtils;
import com.infore.remoteControl.util.ObjectMapperUtil;
import com.infore.remoteControl.util.PageUtil;
import com.infore.remoteControl.util.ResultEntity;

@Service
public class ProtocolDataServiceImpl implements IProtocolDataService {
	
	@Autowired
	IProtocolDataRepository iProtocolDataRepository;
	
	@Autowired
	EntityManager entityManager;
	
	@Autowired
	QueryDispatcher queryDispatcher;
	
	@Autowired
	ObjectMapperUtil ObjectMapperUtil;
	
	@Autowired
	IFileService iFileService;
	
	@Value("${filePath}")
    private String filePath; //文件下载配置路径
	
	@SuppressWarnings("unchecked")
	@Override
	public ResultEntity query(QueryParamDto queryParamDto) {
		ResultEntity resultEntity = null;
		if (queryParamDto == null) { // 无查询条件
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS)
					.setDataList(iProtocolDataRepository.findByOrderByPublishedDateDesc());
		} else if (queryParamDto.getPageObject() != null && queryParamDto.getQueryCondition() == null
				&& queryParamDto.getAssembleCondition() == null && queryParamDto.getAssembleSql() == null) { // 无查询条件只分页
			return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setPage(PageUtil.pageConvert(
					iProtocolDataRepository.findByOrderByPublishedDateDesc(queryParamDto.getPageObject().getPageRequest())));
		} else if (StringUtils.isBlank(queryParamDto.getAssembleSql().getSelect())) { // 不指定任何字段
			return this.queryAll(queryParamDto);
		} else {
			resultEntity = queryDispatcher.dispatcher(queryParamDto, ProtocolData.class);
		}
		// 协议管理页面列表数据作特殊处理
		List<Map<String, Object>> list = ObjectMapperUtil.convertListMap(resultEntity);
		List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
		Map<String, Object> isMap = new HashMap<String, Object>();
		for (Map<String, Object> map : list) {
			String protocol_protocolId = map.get("protocol_protocolId").toString();
			String protocol_protocolType_protocolTypeId = map.get("protocol_protocolType_protocolTypeId").toString();
			String protocol_protocolType_name = map.get("protocol_protocolType_name").toString();
			String id = map.get("id").toString();
			String publishedDate = map.get("publishedDate").toString();
			String protocol_code = map.get("protocol_code").toString();
			String url = map.get("url").toString();
			String protocol_name = map.get("protocol_name").toString();
			String protocol_numbers = map.get("protocol_numbers").toString();
			if (!isMap.containsKey(protocol_protocolId)) {
				Map<String, Object> resultMap = new HashMap<String, Object>();
				// 存入协议文件信息
				List<Map<String, Object>> fileInfoList = new ArrayList<Map<String, Object>>();
				Map<String, Object> fileMap = new HashMap<String, Object>();
				fileMap.put("id", id);
				fileMap.put("publishedDate", publishedDate);
				fileMap.put("url", url.substring(filePath.length())); // 只显示文件名
				fileInfoList.add(fileMap);
				isMap.put(protocol_protocolId, protocol_protocolId);
				isMap.put(protocol_protocolId + "file", fileInfoList);
				// 存入协议信息
				resultMap.put("protocol_protocolId", protocol_protocolId);
				resultMap.put("protocol_protocolType_protocolTypeId", protocol_protocolType_protocolTypeId);
				resultMap.put("protocol_protocolType_name", protocol_protocolType_name);
				resultMap.put("protocol_code", protocol_code);
				resultMap.put("protocol_name", protocol_name);
				resultMap.put("protocol_numbers", protocol_numbers);
				resultMap.put("protocol_file", fileInfoList);
				result.add(resultMap);
			} else {
				List<Map<String, Object>> fileInfoList = (List<Map<String, Object>>) isMap.get(protocol_protocolId + "file");
				Map<String, Object> fileMap = new HashMap<String, Object>();
				fileMap.put("id", id);
				fileMap.put("publishedDate", publishedDate);
				fileMap.put("url", url.substring(filePath.length()));
				fileInfoList.add(fileMap);
			}
		}
		return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(result);
	}

	@Override
	public ResultEntity edit(List<ProtocolData> protocolDataList, MultipartFile file) {
		if (protocolDataList != null && protocolDataList.size() != 0) {
			for (ProtocolData protocolData : protocolDataList) {
				if (StringUtils.isNotBlank(protocolData.getId())) {
					//查询原有的对象
					ProtocolData oldProtocolData = iProtocolDataRepository.findById(protocolData.getId()).orElse(null);
					//判断对象是否存在
					if (oldProtocolData != null) {
						MyBeanUtils.copyNonNullProperties(protocolData,oldProtocolData);
						protocolData = oldProtocolData;
					} else {
						return new ResultEntity(ResultStatus.ERROR, ResultConstants.NO_SUCH_OBJECT);
					}
				}
			}
		}
		return null;
	}

	@Override
	public ResultEntity delete(String ids) {
		// 判断所传入的字符串是否包含逗号,如果包含则表示是删除多条记录
		if (ids.contains(",")) {
			List<String> idList = Arrays.asList(ids.split(","));
			// 通过ID查询
			List<ProtocolData> list = iProtocolDataRepository.findByIdIn(idList);
			// 删除协议数据
			iProtocolDataRepository.deleteByIdIn(idList);
			// 删除文件
			for (ProtocolData protocolData : list) {
				String filePath = protocolData.getUrl();
				iFileService.deleteFile(filePath);
			}
		} else {
			// 通过ID查询
			ProtocolData protocolData = iProtocolDataRepository.findById(ids).orElse(null);
			// 删除协议数据
			iProtocolDataRepository.deleteById(ids);
			// 删除文件
			iFileService.deleteFile(protocolData.getUrl());
		}
		return new ResultEntity(ResultStatus.SUCCESS, Constants.DELETE_SUCCESS);
	}

	@Override
	public ResultEntity validate(ProtocolData protocolData) {
		return null;
	}
	
	// 不指定字段的通用查询
	@SuppressWarnings("serial")
	public ResultEntity queryAll(QueryParamDto queryParamDto) {
		return queryParamDto.getPageObject() != null // 判断是否分页
				? ResultEntity.page(iProtocolDataRepository.findAll(new Specification<ProtocolData>() {
					@Override
					public Predicate toPredicate(Root<ProtocolData> root, CriteriaQuery<?> query,
							CriteriaBuilder criteriaBuilder) {
						// 构建查询条件
						List<Predicate> predicates = QueryUtil.createQueryCondition(queryParamDto,
								criteriaBuilder, root);
						// 组装查询条件
						Predicate predicate = QueryUtil.assembleCondition(queryParamDto, criteriaBuilder,
								predicates);
						// 组装SQL
						QueryUtil.assembleSql(queryParamDto, criteriaBuilder, query, root, predicate);
						return query.getRestriction();
					}
				}, queryParamDto.getPageObject().getPageRequest()))
				: new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS)
						.setDataList(iProtocolDataRepository.findAll(new Specification<ProtocolData>() {
							@Override
							public Predicate toPredicate(Root<ProtocolData> root, CriteriaQuery<?> query,
									CriteriaBuilder criteriaBuilder) {
								// 构建查询条件
								List<Predicate> predicates = QueryUtil.createQueryCondition(queryParamDto,
										criteriaBuilder, root);
								// 组装查询条件
								Predicate predicate = QueryUtil.assembleCondition(queryParamDto, criteriaBuilder,
										predicates);
								// 组装SQL
								QueryUtil.assembleSql(queryParamDto, criteriaBuilder, query, root,
										predicate);
								return query.getRestriction();
							}
						}));
	}

}
